package vip.liux.contracts.infrastructure.messaging.handlers;

import lombok.Setter;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * 组合消息处理器，支持多个子处理器。
 */
public class CompositeMessageHandler implements MessageHandler, InitializingBean {

    private final List<MessageHandler> handlers = new ArrayList<>();
    /**
     * 指定是否在委托列表末尾添加一个
     * 如果启用，任何未被配置的消息处理器处理的消息将由自动处理。
     */
    @Setter
    private boolean fallbackToNoOpCache = false;

    /**
     * 构造一个空的 CompositeMessageHandler，可以通过 {@link #setMessageHandlers "setMessageHandlers"} 方法添加子处理器。
     */
    public CompositeMessageHandler() {
    }

    /**
     * 使用给定的消息处理器构造一个 CompositeMessageHandler。
     *
     * @param messageHandlers 要委托的消息处理器
     */
    public CompositeMessageHandler(MessageHandler... messageHandlers) {
        setMessageHandlers(Arrays.asList(messageHandlers));
    }

    /**
     * 指定要委托的消息处理器。
     *
     * @param messageHandlers 消息处理器集合
     */
    public void setMessageHandlers(Collection<MessageHandler> messageHandlers) {
        this.handlers.addAll(messageHandlers);
    }

    @Override
    public void afterPropertiesSet() {
        if (this.fallbackToNoOpCache) {
            this.handlers.add(new NoOpMessageHandler());
        }
    }

    /**
     * 处理消息，依次调用所有子处理器。
     *
     * @param message 要处理的消息
     * @throws MessagingException 如果处理消息失败
     */
    @Override
    public void handleMessage(@NotNull Message<?> message) throws MessagingException {
        for (MessageHandler handler : handlers) {
            handler.handleMessage(message);
        }
    }

    /**
     * 空操作消息处理器，不执行任何操作。
     */
    static class NoOpMessageHandler implements MessageHandler {
        @Override
        public void handleMessage(@NotNull Message<?> message) throws MessagingException {
            // 不执行任何操作
        }
    }
}